Completed
Push — master ( b89808...cd3036 )
by greg
02:02
created

template.js ➔ ... ➔ ???   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
nc 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
nop 1
1
import fse from 'fs-extra'
2
import {Promise} from 'bluebird'
3
import path from 'path'
4
import {
5
  config,
6
  coreUtils,
7
  cmsData,
8
  abeExtend,
9
  cmsTemplates
10
} from '../../'
11
import * as sourceAttr from '../../cms/editor/handlebars/sourceAttr'
12
13
export function getTemplatesAndPartials(templatesPath) {
14
  var p = new Promise((resolve) => {
15
    const extension = '.' + config.files.templates.extension
16
    return coreUtils.file.getFilesAsync(templatesPath, true, extension)
17
      .then(function(files){
18
        return resolve(files)
19
      })
20
  })
21
22
  return p
23
}
24
25
export function addOrder(text) {
26
  var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g
27
  var matches = text.match(regAbe)
28
  var order = 0
29
  
30
  if(typeof matches !== 'undefined' && matches !== null){
31
    Array.prototype.forEach.call(matches, (match) => {
32
      if(typeof match !== 'undefined' && match !== null) {
33
        
34
        var orderAttr = cmsData.regex.getAttr(match, 'order')
35
36
        if(typeof orderAttr === 'undefined' || orderAttr === null || orderAttr === '') {
37
          var matchOrder = match.replace(/\}\}$/, ` order='${order}'}}`)
38
          text = text.replace(match, matchOrder)
39
        }
40
        order++
41
      }
42
    })
43
  }
44
  return text
45
}
46
47
export function getAbeImport(text) {
48
  var partials = []
49
  let listReg = /({{abe.*type=[\'|\"]import.*}})/g
50
  var match
51
  while (match = listReg.exec(text)) {
52
    partials.push(match[0])
53
  }
54
55
  return partials
56
}
57
58
export function includePartials(text, json) {
59
  var abeImports = cmsTemplates.template.getAbeImport(text)
60
61
  Array.prototype.forEach.call(abeImports, (abeImport) => {
62
    var obj = cmsData.attributes.getAll(abeImport, {})
63
64
    var file = obj.file
65
    var partial = ''
66
    file = path.join(config.root, config.partials, file)
67
68
    if (file.indexOf('{{') > -1) {
69
      var keys = sourceAttr.getKeys(file)
70
      Array.prototype.forEach.call(keys, (key) => {
71
        try {
72
          var toEval = `${key.replace(/(\[|\.|\])/g, '\\$1')}`
73
          file = file.replace(new RegExp(`\{\{${toEval}\}\}`, 'g'), eval(`json.${key}`))
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
74
        }catch(e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
75
        }
76
      })
77
    }
78
    
79
    if(coreUtils.file.exist(file)) {
80
      partial = cmsTemplates.template.includePartials(fse.readFileSync(file, 'utf8'), json)
81
    }
82
    text = text.replace(cmsData.regex.escapeTextToRegex(abeImport, 'g'), partial)
83
  })
84
85
  return text
86
}
87
88
export function translate(text) {
89
  var importReg = /({{abe.*type=[\'|\"]translate.*}})/g
90
91
  var matches = text.match(importReg)
92
  
93
  if(typeof matches !== 'undefined' && matches !== null) {
94
    Array.prototype.forEach.call(matches, (match) => {
95
      var splitedMatches = match.split('{{abe ')
96
97
      Array.prototype.forEach.call(splitedMatches, (splitedMatch) => {
98
        var currentMatch = `{{abe ${splitedMatch}`
99
        if(/({{abe.*type=[\'|\"]translate.*}})/.test(currentMatch)) {
100
          var locale = cmsData.regex.getAttr(currentMatch, 'locale')
101
          var source = cmsData.regex.getAttr(currentMatch, 'source')
102
103
          if (locale.indexOf('{{') === -1) {
104
            locale = `'${locale}'`
105
          }else {
106
            locale = locale.replace(/\{\{(.*?)\}\}/, '$1')
107
          }
108
109
          if (source.indexOf('{{') === -1) {
110
            source = `'${source.replace(/'/g, '\\\'')}'`
111
          }else {
112
            source = source.replace(/\{\{(.*?)\}\}/, '$1')
113
          }
114
115
          // var replace = `{{{i18nAbe ${locale} ${source}}}}`
116
          var replace = currentMatch.replace('{{abe', '{{i18nAbe')
117
          replace = replace.replace(/locale=['|"].*?['|"]/, locale)
118
          replace = replace.replace(/source=['|"].*?['|"]/, source)
119
          replace = replace.replace(/{{i18nAbe.*?}}/, `{{{i18nAbe ${locale} ${source}}}}`)
120
121
          text = text.replace(cmsData.regex.escapeTextToRegex(currentMatch, 'g'), replace)
122
        }
123
      })
124
    })
125
  }
126
127
  return text
128
}
129
130
export function getTemplate (file, json = {}) {
131
  var text = ''
132
133
  // HOOKS beforeGetTemplate
134
  file = abeExtend.hooks.instance.trigger('beforeGetTemplate', file)
135
136
  file = file.replace(path.join(config.root, config.templates.url), '')
137
  file = file.replace(config.root, '')
138
  if (file.indexOf('.') > -1) {
139
    file = file.replace(/\..+$/, '')
140
  }
141
  file = path.join(config.root, config.templates.url, file + '.' + config.files.templates.extension)
142
  if(coreUtils.file.exist(file)) {
143
    text = fse.readFileSync(file, 'utf8')
144
    text = cmsTemplates.template.includePartials(text, json)
145
    text = cmsTemplates.template.translate(text)
146
    text = cmsTemplates.template.addOrder(text)
147
  }else {
148
    text = `[ ERROR ] template ${file + '.' + config.files.templates.extension} doesn't exist anymore`
149
  }
150
151
  // HOOKS afterGetTemplate
152
  text = abeExtend.hooks.instance.trigger('afterGetTemplate', text)
153
154
  return text
155
}
156
157
export function getVariablesInWhere(where) {
158
  var ar = []
159
160
  if(where.left.column.indexOf('{{') > -1) {
161
    ar.push(where.left.column.replace(/\{\{(.*?)\}\}/, '$1'))
162
  }
163
  else{
164
    ar.push(where.left.column)
165
  }
166
167
  if (where.right.value) {
168
    if (typeof where.right.value === 'string') {
169
      if(where.right.value && where.right.value.indexOf('{{') > -1) {
170
        ar.push(where.right.value.replace(/\{\{(.*?)\}\}/, '$1'))
171
      }
172
    }else {
173
      where.right.value.forEach(function (value) {
174
        if(value.column.indexOf('{{') > -1) {
175
          ar.push(value.column.replace(/\{\{(.*?)\}\}/, '$1'))
176
        }
177
      })
178
    }
179
  }
180
181
  if(where.right.column && where.right.column.indexOf('{{') > -1) {
182
    ar.push(where.right.column.replace(/\{\{(.*?)\}\}/, '$1'))
183
  }
184
185
  return ar
186
}
187
188
/**
189
 * Get columns and where.left ids of a select statement
190
 *
191
 * select title, image from ../ where template=""
192
 *
193
 * return [title, image, template]
194
 * 
195
 * @param  {Array} templatesList ["article.html", "other.html"]
0 ignored issues
show
Documentation introduced by
The parameter templatesList does not exist. Did you maybe forget to remove this comment?
Loading history...
196
 * @return {Promise}
197
 */
198
export function recurseWhereVariables (where) {
199
  var ar = []
0 ignored issues
show
Unused Code introduced by
The assignment to variable ar seems to be never used. Consider removing it.
Loading history...
200
  var arLeft
201
  var arRight
202
  switch(where.operator) {
203
  case 'AND':
204
    arLeft = cmsTemplates.template.recurseWhereVariables(where.left)
205
    arRight = cmsTemplates.template.recurseWhereVariables(where.right)
206
    return arLeft.concat(arRight)
207
    break
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
208
  case 'OR':
209
    arLeft = cmsTemplates.template.recurseWhereVariables(where.left)
210
    arRight = cmsTemplates.template.recurseWhereVariables(where.right)
211
    return arLeft.concat(arRight)
212
    break
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
213
  default:
214
    ar = getVariablesInWhere(where)
215
    break
216
  }
217
218
  return ar
219
}
220
221
export function getTemplatesTexts(templatesList, json) {
222
  var templates = []
223
  var p = new Promise((resolve) => {
224
    Array.prototype.forEach.call(templatesList, (file) => {
225
      var template = fse.readFileSync(file, 'utf8')
226
      template = cmsTemplates.template.includePartials(template, json)
227
      var name = file.replace(path.join(config.root, config.templates.url, path.sep), '').replace(`.${config.files.templates.extension}`, '')
228
      templates.push({
229
        name: name,
230
        path: file,
231
        template: template
232
      })
233
    })
234
    resolve(templates)
235
  })
236
237
  return p
238
}
239
240
export function execRequestColumns(tpl) {
241
  var ar = []
242
  var matches = cmsData.regex.getTagAbeTypeRequest(tpl)
243
  Array.prototype.forEach.call(matches, (match) => {
244
    var obj = cmsData.attributes.getAll(match[0], {})
245
    var type = cmsData.sql.getSourceType(obj.sourceString)
246
    switch (type) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
247
    case 'request':
248
      var request = cmsData.sql.handleSqlRequest(obj.sourceString, {})
249
      if(typeof request.columns !== 'undefined' && request.columns !== null) {
250
        Array.prototype.forEach.call(request.columns, (column) => {
251
          ar.push(column)
252
        })
253
      }
254
      if(typeof request.where !== 'undefined' && request.where !== null) {
255
        ar = ar.concat(cmsTemplates.template.recurseWhereVariables(request.where))
256
      }
257
    }
258
  })
259
260
  return ar
261
}
262
263
export function getAbeRequestWhereKeysFromTemplates(templatesList) {
264
  var whereKeys = []
265
  var p = new Promise((resolve) => {
266
    Array.prototype.forEach.call(templatesList, (file) => {
267
      whereKeys = whereKeys.concat(cmsTemplates.template.execRequestColumns(file.template))
268
    })
269
    whereKeys = whereKeys.filter(function (item, pos) {return whereKeys.indexOf(item) == pos})
270
    resolve(whereKeys)
271
  })
272
273
  return p
274
}
275
276
export function setAbeSlugDefaultValueIfDoesntExist(templateText) {
277
  var matches = cmsData.regex.getTagAbeWithType(templateText, 'slug')
278
  if(matches == null || matches[0] == null) {
279
    templateText = `{{abe type="slug" source="{{name}}"}}\n${templateText}`
280
  }
281
282
  return templateText
283
}
284
285
export function getAbeSlugFromTemplates(templatesList) {
286
  var slugs = {}
287
  Array.prototype.forEach.call(templatesList, (file) => {
288
    var templateText = cmsTemplates.template.setAbeSlugDefaultValueIfDoesntExist(file.template)
289
    var matchesSlug = cmsData.regex.getTagAbeWithType(templateText, 'slug')
290
    var obj = cmsData.attributes.getAll(matchesSlug[0], {})
291
    slugs[file.name] = obj.sourceString
292
  })
293
  return slugs
294
}
295
296
export function setAbePrecontribDefaultValueIfDoesntExist(templateText) {
297
  var matches = cmsData.regex.getTagAbeWithTab(templateText, 'slug')
298
  if(matches == null || matches[0] == null) {
299
    templateText = `{{abe type='text' key='name' desc='Name' required="true" tab="slug" visible="false"}}\n${templateText}`
300
  }
301
302
  return templateText
303
}
304
305
export function getAbePrecontribFromTemplates(templatesList) {
306
  var fields = []
307
  var precontributionTemplate = ''
308
  Array.prototype.forEach.call(templatesList, (file) => {
309
    var slugMatch = cmsData.regex.getTagAbeWithType(file.template, 'slug')
310
    var templateText = file.template
311
    if(slugMatch == null || slugMatch[0] == null) {
312
      templateText = cmsTemplates.template.setAbePrecontribDefaultValueIfDoesntExist(file.template)
313
    }
314
315
    var matchesTabSlug = cmsData.regex.getTagAbeWithTab(templateText, 'slug')
316
    Array.prototype.forEach.call(matchesTabSlug, (match) => {
317
      fields.push(cmsData.attributes.getAll(match, {}))
318
      var tag = match.replace(/\}\}$/, ' precontribTemplate="' + file.name + '"}}')
319
      tag = tag.replace(/(key=[\'|\"])(.*?)([\'|\"])/, '$1/' + file.name + '/$2$3')
320
      precontributionTemplate += `${tag}\n`
321
    })
322
  })
323
324
  precontributionTemplate = cmsTemplates.template.addOrder(precontributionTemplate)
325
326
  return {
327
    fields: fields,
328
    template: precontributionTemplate
329
  }
330
}
331
332
export function getStructureAndTemplates() {
333
  const pathStructure = path.join(config.root, config.structure.url)
334
  const pathTemplates = path.join(config.root, config.templates.url)
335
  const extension = '.' + config.files.templates.extension
336
  let result = {'structure': [], 'templates': []}
337
338
  result.structure = coreUtils.file.getFoldersSync(pathStructure, true)
339
  let templatePaths = coreUtils.file.getFilesSync(pathTemplates, true, extension)
340
  Array.prototype.forEach.call(templatePaths, (templatePath) => {
341
    let additionalPath = path.dirname(templatePath).replace(pathTemplates,'')
342
    if(additionalPath !== '') additionalPath = additionalPath.substring(1)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
343
    let name = path.join(additionalPath,path.basename(templatePath,extension))
344
    let template = {'path':templatePath, 'name':name}
345
    result.templates.push(template)
346
  })
347
348
  return result
349
}